package net.bac.sbe.web.sonar.server.dev.utils.xml.applications;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.xml.bind.JAXBException;

import net.bac.sbe.web.sonar.client.view.ApplicationView;
import net.bac.sbe.web.sonar.client.view.ModuleView;
import net.bac.sbe.web.sonar.client.view.RepositoryView;
import net.bac.sbe.web.sonar.server.dev.utils.xml.XmlBinding;
import sbe.sonar.client.database.Application;
import sbe.sonar.client.database.Module;
import sbe.sonar.client.database.Repository;
import sbe.sonar.client.database.dao.GSBEEntityManagerFactory;

public class ApplicationsConfig {
	private RepositoriesType repositoriesType;
	private static ApplicationsConfig instance;

	public String getApplicationByRegularExpression(String path) {
		String result = "";
		for (RepositoryType repository : repositoriesType.getRepository()) {

			if (null != repository.getApplications()) {
				for (ApplicationType appType : repository.getApplications()
						.getApplication()) {
					if (path.matches(appType.getRegularExpression())) {
						result = appType.getName();
						break;
					}
				}
			}
		}
		return result;
	}

	public String getModuleByRegularExpression(String path) {
		String result = "";
		for (RepositoryType repository : repositoriesType.getRepository()) {
			if (null != repository.getApplications()) {
				for (ApplicationType appType : repository.getApplications()
						.getApplication()) {
					if(null != appType.getModules()){
						for (ModuleType module : appType.getModules().getModule()) {
							if (path.matches(module.getRegularExpression())) {
								result = module.getName();
								break;
							}
						}
					}
				}
			}
		}
		return result;
	}

	public ModuleType getModuleConfigByRegularExpression(String path) {
		ModuleType result = null;
		for (RepositoryType repository : repositoriesType.getRepository()) {
			if (null != repository.getApplications()) {
				for (ApplicationType appType : repository.getApplications()
						.getApplication()) {
					if(null != appType.getModules()){
						for (ModuleType module : appType.getModules().getModule()) {
							if (path.matches(module.getRegularExpression())) {
								result = module;
								break;
							}
						}
					}
				}
			}
		}
		return result;
	}

	public String getRepositoryURL(String repositoryName) {
		String result = "";
		for (RepositoryType repository : repositoriesType.getRepository()) {
			if (repository.getName().equals(repositoryName)) {
				result = repository.getSvnurl();
				break;
			}
		}
		return result;

	}

	public void getTest() {
	}

	public List<RepositoryType> getRepositories() {
		return repositoriesType.getRepository();
	}

	public static ApplicationsConfig getInstance() {
		if (null == instance) {
			init();
		}
		return instance;
	}

	private static void init() {
		instance = new ApplicationsConfig();
//		instance.repositoriesType = XmlBinding
//				.getInstance()
//				.xmlResourceToObject(
//						ApplicationsConfig.class
//								.getResourceAsStream("/net/bac/sbe/web/applications/config/sbe-applications-config.xml"),
//						RepositoriesType.class);
//		
		
		
		
		EntityManager em = GSBEEntityManagerFactory.getDefaultEntityManager();
		em.getTransaction().begin();
		
//		
//		for (RepositoryType repo : instance.repositoriesType.getRepository()) {
//			
//			Repository rep = new Repository();
//			rep.setIdRepository(repo.getName());
//			rep.setSvnurl(repo.getSvnurl());
//			
//			rep.setApplications(new ArrayList<Application>());
//			
//			
//			
//			for (ApplicationType app : repo.getApplications().getApplication()) {
//				
//				Application appEn = new Application();
//				appEn.setIdApplication(app.getName());
//				appEn.setRegularExpression(app.getRegularExpression());
//				appEn.setSonarKey(app.getSonarKey());
//				
//				
//				rep.getApplications().add(appEn);
//
//							
//				if(app.getModules() != null && app.getModules().getModule() != null){
//					appEn.setModules(new ArrayList<Module>());
//					for (ModuleType module : app.getModules().getModule()) {
//						Module mod = new Module();
//						mod.setIdModule(module.getName());
//						mod.setArtifactId(module.getArtifactId());
//						mod.setRegularExpression(module.getRegularExpression());
//						mod.setSonarKey(module.getSonarKey());
//						mod.setSourcePath(module.getSourcePath());
//						
//						appEn.getModules().add(mod);
//						
//					}
//				}
//			}
//			
//			em.persist(rep);
//		}
//		
//		
//		
//		em.getTransaction().commit();
//		//-----------------------------------------------------------
		
		TypedQuery<Repository> query = em.createNamedQuery("Repository.findAll", Repository.class);
		
		List<Repository> repositories = query.getResultList();
		
		em.getTransaction().commit();
		
		RepositoriesType localRepositoriesType = new RepositoriesType();
		
		for (Repository repository : repositories) {
			RepositoryType repositoryType = new RepositoryType();
			repositoryType.setName(repository.getIdRepository());
			repositoryType.setSvnurl(repository.getSvnurl());
			
			ApplicationsType applicationsType = new ApplicationsType();
			for (Application application : repository.getApplications()) {
				ApplicationType applicationType = new ApplicationType();
				applicationType.setName(application.getIdApplication());
				applicationType.setRegularExpression(application.getRegularExpression());
				applicationType.setSonarKey(application.getSonarKey());
				
				
				ModulesType modulesType = new ModulesType();
				for (Module module : application.getModules()) {
					ModuleType moduleType = new ModuleType();
					moduleType.setArtifactId(module.getArtifactId());
					moduleType.setName(module.getIdModule());
					moduleType.setRegularExpression(module.getRegularExpression());
					moduleType.setSonarKey(module.getSonarKey());
					moduleType.setSourcePath(module.getSourcePath());
					modulesType.getModule().add(moduleType);
				}
				
				applicationType.setModules(modulesType);
				applicationsType.getApplication().add(applicationType);
			}
			
			repositoryType.setApplications(applicationsType);
			localRepositoriesType.getRepository().add(repositoryType);
		}
		
		instance.repositoriesType = localRepositoriesType;
	}

	public boolean addRepository(RepositoryView view){

//		RepositoryType repType = new RepositoryType();
//		ApplicationsType appsType = new ApplicationsType();
//		appsType.application = new ArrayList<ApplicationType>(view.getApplications().size());
		
		
		//Guardo el nuevo repositorio en Base de Datos
		EntityManager em = GSBEEntityManagerFactory.getDefaultEntityManager();
		em.getTransaction().begin();
		
		
		//Creo el repositorio
		Repository repositoryEntity = new Repository();
		repositoryEntity.setIdRepository(view.getRepositoryName());
		repositoryEntity.setSvnurl(view.getSvnURL());
		repositoryEntity.setApplications(new ArrayList<Application>());
		
		
		for (ApplicationView appView : view.getApplications()) {
			//Incluyo cada aplicacion en la base de datos
			Application applicationEntity = new Application();
			applicationEntity.setIdApplication(appView.getName());
			applicationEntity.setRegularExpression(appView.getRegularExpression());
			applicationEntity.setSonarKey(appView.getSonarKey());
			//Agrego la entidad a las aplicaciones del repositorio		
			
			
//			ApplicationType appType = new ApplicationType();

//			appType.setName(appView.getName());
//			appType.setRegularExpression(appView.getRegularExpression());

			if(null != appView.getModules()){
//				ModulesType modulesType = new ModulesType();
//				modulesType.setModule(new ArrayList<ModuleType>(appView.getModules().size()));
				
				applicationEntity.setModules(new ArrayList<Module>());
				
				for (ModuleView moduleView : appView.getModules()) {
					
					Module moduleEntity = new Module();
					moduleEntity.setArtifactId(moduleView.getArtifactId());
					moduleEntity.setIdModule(moduleView.getName());
					moduleEntity.setRegularExpression(moduleView.getRegularExpression());
					moduleEntity.setSonarKey(moduleView.getSonarKey());
//					moduleEntity.setSourcePath(moduleView.getSourcePath());
					
					
//					ModuleType moduleType = new ModuleType();
//					moduleType.setArtifactId(moduleView.getArtifactId());
//					moduleType.setName(moduleView.getName());
//					moduleType.setRegularExpression(moduleView.getRegularExpression());
//					moduleType.setSonarKey(moduleView.getSonarKey());
//					modulesType.getModule().add(moduleType);
					applicationEntity.getModules().add(moduleEntity);
				}
//				appType.setModules(modulesType);
				
			}
			repositoryEntity.getApplications().add(applicationEntity);
//			appsType.application.add(appType);
		}


//		repType.setApplications(appsType);
//		repType.setName(view.getRepositoryName());
//		repType.setSvnurl(view.getSvnURL());
//
//
//		instance.repositoriesType.repository.add(repType);

		//Guardado de los cambios en la base de datos
		em.persist(repositoryEntity);
		em.getTransaction().commit();
		
		init();
		
		return true;
	}

	private boolean saveConfigurationChanges() {
		try {
			String xmlConfiguration = XmlBinding.getInstance().objectToXml(instance.repositoriesType);
			URL url = ApplicationsConfig.class.getResource("/net/bac/sbe/web/applications/config/sbe-applications-config.xml");
			System.out.println("PATH: " + url.getPath());
			String path = url.getPath();

			File file = new File(path);
			file.delete();

			FileOutputStream fos = new FileOutputStream(path);
			fos.write(xmlConfiguration.getBytes());
			fos.close();

			return true;

		} catch (JAXBException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * Rutina que borra una aplicación
	 * @param repositoryName
	 * @return boolean con el resultado de la aplicación
	 */
	public boolean deleteRepository(String repositoryName){

		EntityManager em = GSBEEntityManagerFactory.getDefaultEntityManager();
		em.getTransaction().begin();
		
		Repository repoToDelete = em.find(Repository.class, repositoryName);
		
		em.remove(repoToDelete);
		
		em.getTransaction().commit();
		
		init();
		
//		for (int i = 0; i < repositoriesType.getRepository().size(); i++) {
//			RepositoryType repository = repositoriesType.getRepository().get(i);
//			if (repository.getName().equals(repositoryName)) {
//				repositoriesType.getRepository().remove(i);
//				break;
//			}
//		}
		
		

		return true;
	}

}
